import {LitElement, css} from "lit";

const observedForElements = new Set();
//type ContentDirectionManager = HTMLElement & {
//     startManagingContentDirection?(): void;
// };

/**
 * @typedef { HTMLElement & {startManagingContentDirection?(): void}} ContentDirectionManager
 */

/**
 *
 * @param {ContentDirectionManager} el
 * @return {boolean}
 */
const canManageContentDirection = (el) =>
    typeof el.startManagingContentDirection !== 'undefined' ||
    el.tagName === 'SP-THEME';

const SpectrumMixin = () => class SpectrumMixinElement extends LitElement {

    /**
     * @private
     * @type {HTMLElement}
     */
    _dirParent;

    hasVisibleFocusInTree() {
        const activeElement = this.getRootNode().activeElement;
        if (!activeElement) {
            return false;
        }
        try {
            return (
                activeElement.matches(":focus-visible") ||
                activeElement.matches(".focus-visible")
            );
        } catch (error) {
            return activeElement.matches(".focus-visible");
        }
    }

    /**
     * @override
     */
    connectedCallback() {
        if (!this.hasAttribute('dir')) {
            let dirParent = this.assignedSlot ||
                this.parentNode;
            while (
                dirParent !== document.documentElement &&
                !canManageContentDirection(
                    dirParent
                )
                ) {
                dirParent = dirParent.assignedSlot || // step into the shadow DOM of the parent of a slotted node
                    dirParent.parentNode || // DOM Element detected
                    dirParent.host;
            }
            this.dir =
                dirParent.dir === 'rtl' ? dirParent.dir : this.dir || 'ltr';
            if (dirParent === document.documentElement) {
                observedForElements.add(this);
            } else {
                const {localName} = dirParent;
                if (
                    localName.search('-') > -1 &&
                    !customElements.get(localName)
                ) {
                    customElements.whenDefined(localName).then(() => {
                        dirParent.startManagingContentDirection(this);
                    });
                } else {
                    dirParent.startManagingContentDirection(
                        this
                    );
                }
            }
            this._dirParent = dirParent;
        }
        super.connectedCallback();
    }

    disconnectedCallback() {
        super.disconnectedCallback();
        if (this._dirParent) {
            if (this._dirParent === document.documentElement) {
                observedForElements.delete(this);
            } else {
                this._dirParent.stopManagingContentDirection(
                    this
                );
            }
            this.removeAttribute('dir');
        }
    }
}

/**
 * @extends {SpectrumMixinElement}
 */
export class SpectrumElement extends SpectrumMixin() {
    static get styles() {
        return css`
          :host {
            display: block;
          }

          .tool {
            border: 1px solid #000;
          }
        `
    }
}


